﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Windows.Input;
using RG.Common.Configuration;
using RG.Common.WPF.Commands;
using RG.Common.WPF.Dialogs;
using RG.Common.WPF.Settings;
using Microsoft.Practices.Unity;
using RG.Common;
using RG.Common.Configuration;

namespace RG.Common.WPF.Workplaces
{
   
    [SupportDataBinding]
    public class OneFrameWorkplaceVM : BaseFrameWorkplace
    {
        
        
        public DelegateCommand<FrameTab> CloseFrameCmd { get; set; }
        
        [InjectionConstructor]
        public OneFrameWorkplaceVM(IUnityContainer parentCfg, IWorkplace parentWorkplace)
            : base(parentCfg, parentWorkplace)
        {
            CloseFrameCmd = new DelegateCommand<FrameTab>(DoCloseFrame);
        }

        public void ShowNew(FrameDescVM fiVM)
        {
            if (fiVM.Item is FrameSingle)
            {
                var typeofWorkplace = typeof(OneFrameWorkplaceVM);

                var methodInfo = typeofWorkplace.GetMethod("CreateTab");
                var fs = (FrameSingle)fiVM.Item;
                var genericArguments = new[] { fs.Type };
                var genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
                var presenter = Cfg.Resolve(fs.Type);
                // Это зовется IWorkplace.CreateTab<T>(presenter)
                genericMethodInfo.Invoke(this, new[] { presenter, fiVM });
            }
        }

        public void CreateTab<TPresenter>(TPresenter presenter, FrameDescVM fiVM)
        {
            var v = Cfg.Resolve<IView<TPresenter>>();
            v.Presenter = presenter;

            var config = (fiVM != null) ? fiVM.Config : new FrameConfigSettings { Id = presenter.GetType().GUID };

            var tab = new FrameTab
                          {
                              Presenter = presenter,
                              View = v,
                              FrameDescVM = fiVM,
                              Config = config,
                              PresenterSettings = Cfg.Resolve<IApplicationSettings>(),
                              ViewSettings = new WpfSettings()
                          };

            tab.PresenterSettings.Bind(tab.Config.Id.ToString(), presenter);
            tab.PresenterSettings.Load();
            tab.ViewSettings.Bind(tab.Config.Id.ToString(), v);
            tab.ViewSettings.Load();
            tab.Num = Tabs.Count;
            

            if (presenter is IFrameForMultiWorkplace)
            {
                var frame = (IFrameForMultiWorkplace)presenter;
                if (fiVM != null)
                    frame.Name = fiVM.Name;
                
            }

            Tabs.Add(tab);
            SelectedTab = tab;

        }

        [DependOn("SelectedTab")] // Активность/неактивность кнопки закрытия фрейма
        public bool BtnCloseEnabled { get { return Tabs.IndexOf(SelectedTab) > 0; } }

        public FrameTab SelectedTab // Эту штуку мы показываем (название историческое)
        {
            get { return selectedTab; }
            set
            {
                if (selectedTab != null) selectedTab.PresenterSettings.Save();
                selectedTab = value;
                if (value != null) // При смене фрейма меняем список доступных для него сеттингов
                {
                    UpdateSettingsArray(0); // и загружаем то, что было в последний раз (0)
                    if (Tabs.IndexOf(value) > 0)
                    {                                                   // Если показываемый фрейм - не заглавный
                        Tabs.Move(Tabs.IndexOf(value), Tabs.Count - 1); // двигаем историю открытых фреймов
                        selectedTab = Tabs[Tabs.Count - 1];             // и показываем последний
                    }
                    else
                        selectedTab = Tabs[0];
                }
            }
        }


        public bool CloseTab(object presenter)
        {
            if (Tabs.Count == 0) return false; // На всякий случай
            FrameTab tab;
            if (!FindTabFor(presenter, out tab)) return false;
            if (tab.Config.FilterSaveType == SaveType.SaveTypeOnClose)
                tab.PresenterSettings.Save();
            if (tab.Config.ColumnsSaveType == SaveType.SaveTypeOnClose)
                tab.ViewSettings.Save();
            Tabs.Remove(tab);
            tab = null;
            SelectedTab = Tabs.Count > 0 ? Tabs[Tabs.Count - 1] : null; // Если есть, чего показать ещё - показываем
            return true;
        }

        public bool FindTabFor(object presenter, out FrameTab tab)
        {
            if (presenter == null && Tabs.Count>0)
            {
                tab = Tabs[Tabs.Count - 1];
                return true;
            }
            tab = null;
            foreach (var t in Tabs)
                if (t.Presenter == presenter)
                {
                    tab = t;
                    break;
                }
            return (tab != null);
        }

        public void Show(FrameDescVM fiVM)
        {
           ShowNew(fiVM);
        }

       public void DoCloseFrame(FrameTab frameNum)
        {
            var frame = frameNum.Presenter as IFrameForMultiWorkplace;

            if (frame == null || frame.CanClose)
            {
                for (int i = 1; i < Tabs.Count;i++)
                {
                    if (Tabs[i].Num>frameNum.Num)
                        Tabs[i].Num = Tabs[i].Num - 1;
                }
                CloseTab(frameNum.Presenter);
            }
        }
        
        
        public override void Show<T>(T presenter)
        {
            CreateTab(presenter, null);
        }

        public override void Close(object presenter)
        {
            if (Tabs.Count == 0) return;
            if (((IFrameForMultiWorkplace)Tabs[Tabs.Count-1].Presenter).CanClose)
                CloseTab(presenter);
        }

        public override void ShowAlarm<TalarmManager>(TalarmManager frame, int id)
        {
            
        }

        public override void CloseAlarm()
        {
            
        }

        public override bool CanClose
        {
            get
            {
                while (Tabs.Count > 0)
                {
                    if (((IFrameForMultiWorkplace)Tabs[Tabs.Count - 1].Presenter).CanClose)
                        CloseTab(Tabs[Tabs.Count-1].Presenter);
                    else
                        return false;
                }
                presenterSettings.Save();
                return true;
            }
        }

       
    }
}

